#include "stdafx.h"
#include "CPrinterConfig.h"

#include "dcmtk/ofstd/ofconfig.h"    /* for class OFConfigFile */

#define L0_AETITLE                      "AETITLE"
#define L0_BORDERDENSITY                "BORDERDENSITY"
#define L0_DESCRIPTION                  "DESCRIPTION"
#define L0_DISABLENEWVRS                "DISABLENEWVRS"
#define L0_DISPLAYFORMAT                "DISPLAYFORMAT"
#define L0_EMPTYIMAGEDENSITY            "EMPTYIMAGEDENSITY"
#define L0_FILMDESTINATION              "FILMDESTINATION"
#define L0_FILMSIZEID                   "FILMSIZEID"
#define L0_HOSTNAME                     "HOSTNAME"
#define L0_IMPLICITONLY                 "IMPLICITONLY"
#define L0_MAGNIFICATIONTYPE            "MAGNIFICATIONTYPE"
#define L0_MAXDENSITY                   "MAXDENSITY"
#define L0_MAXPDU                       "MAXPDU"
#define L0_MEDIUMTYPE                   "MEDIUMTYPE"
#define L0_MINDENSITY                   "MINDENSITY"
#define L0_OMITSOPCLASSUIDFROMCREATERESPONSE "OMITSOPCLASSUIDFROMCREATERESPONSE"
#define L0_PORT                         "PORT"
#define L0_PRESENTATIONLUTINFILMSESSION "PRESENTATIONLUTINFILMSESSION"
#define L0_PRESENTATIONLUTMATCHREQUIRED "PRESENTATIONLUTMATCHREQUIRED"
#define L0_RESOLUTIONID                 "RESOLUTIONID"
#define L0_SMOOTHINGTYPE                "SMOOTHINGTYPE"
#define L0_SUPPORTS12BIT                "SUPPORTS12BIT"
#define L0_SUPPORTSDECIMATECROP         "SUPPORTSDECIMATECROP"
#define L0_SUPPORTSIMAGESIZE            "SUPPORTSIMAGESIZE"
#define L0_SUPPORTSPRESENTATIONLUT      "SUPPORTSPRESENTATIONLUT"
#define L0_SUPPORTSTRIM                 "SUPPORTSTRIM"
#define L0_TYPE                         "TYPE"
#define L2_COMMUNICATION                "COMMUNICATION"

CPrinterConfig::CPrinterConfig(const char *config_file /*= NULL*/)
{
	if (config_file)
	{
		FILE *cfgfile = NULL;
		fopen_s(&cfgfile, config_file, "rb");
		if (cfgfile)
		{
			m_pConfig = new OFConfigFile(cfgfile);
			fclose(cfgfile);
		}
	}
}

CPrinterConfig::~CPrinterConfig(void)
{
	if (m_pConfig) 
		delete m_pConfig;
}

int CPrinterConfig::GetNumberOfPrinter()
{
	int result = 0;

	if (m_pConfig)
	{
		m_pConfig->set_section(2, L2_COMMUNICATION);
		if (m_pConfig->section_valid(2))
		{
			m_pConfig->first_section(1);
			while (m_pConfig->section_valid(1))
			{
				std::string type = m_pConfig->get_entry(L0_TYPE);

				if (_stricmp(type.c_str(), "PRINTER") == 0 || _stricmp(type.c_str(), "LOCALPRINTER") == 0)
					result++;

				m_pConfig->next_section(1);
			}
		}
	}

	return result;
}

int CPrinterConfig::GetPrinters(vec_dcmprinter_type& vec)
{
	if (m_pConfig)
	{
		m_pConfig->set_section(2, L2_COMMUNICATION);
		if (m_pConfig->section_valid(2))
		{
			m_pConfig->first_section(1);
			while (m_pConfig->section_valid(1))
			{
				std::string type = m_pConfig->get_entry(L0_TYPE);

				if (_stricmp(type.c_str(), "PRINTER") == 0 || _stricmp(type.c_str(), "LOCALPRINTER") == 0)
				{
					DCMPRINTER printer;
					printer.PrinterName = m_pConfig->get_keyword(1);
					printer.Aetitle = getConfigEntry(L2_COMMUNICATION, printer.PrinterName.c_str(), L0_AETITLE);//m_pConfig->get_entry(L0_AETITLE);
					printer.Description = getConfigEntry(L2_COMMUNICATION, printer.PrinterName.c_str(), L0_DESCRIPTION);//m_pConfig->get_entry(L0_DESCRIPTION);
					printer.Hostname = getConfigEntry(L2_COMMUNICATION, printer.PrinterName.c_str(), L0_HOSTNAME);//m_pConfig->get_entry(L0_HOSTNAME);
					printer.Port = getConfigEntry(L2_COMMUNICATION, printer.PrinterName.c_str(), L0_PORT);//m_pConfig->get_entry(L0_PORT);
					printer.Type = type;
					printer.BorderDensity = getConfigEntry(L2_COMMUNICATION, printer.PrinterName.c_str(), L0_BORDERDENSITY);//m_pConfig->get_entry(L0_BORDERDENSITY);
					printer.DisableNewVRs = getConfigBoolEntry(L2_COMMUNICATION, printer.PrinterName.c_str(), L0_DISABLENEWVRS, false);
					printer.DisplayFormat = getConfigEntry(L2_COMMUNICATION, printer.PrinterName.c_str(), L0_DISPLAYFORMAT);//m_pConfig->get_entry(L0_DISPLAYFORMAT);
					printer.EmptyImageDensity = getConfigEntry(L2_COMMUNICATION, printer.PrinterName.c_str(), L0_EMPTYIMAGEDENSITY);//m_pConfig->get_entry(L0_EMPTYIMAGEDENSITY);
					printer.FilmDestination = getConfigEntry(L2_COMMUNICATION, printer.PrinterName.c_str(), L0_FILMDESTINATION);//m_pConfig->get_entry(L0_FILMDESTINATION);
					printer.FilmSizeID = getConfigEntry(L2_COMMUNICATION, printer.PrinterName.c_str(), L0_FILMSIZEID);//m_pConfig->get_entry(L0_FILMSIZEID);
					printer.ImplicitOnly = getConfigBoolEntry(L2_COMMUNICATION, printer.PrinterName.c_str(), L0_IMPLICITONLY, false);
					printer.MagnificationType = getConfigEntry(L2_COMMUNICATION, printer.PrinterName.c_str(), L0_MAGNIFICATIONTYPE);//m_pConfig->get_entry(L0_MAGNIFICATIONTYPE);
					printer.MaxDensity = getConfigEntry(L2_COMMUNICATION, printer.PrinterName.c_str(), L0_MAXDENSITY);//m_pConfig->get_entry(L0_MAXDENSITY);
					printer.MaxPDU = getConfigEntry(L2_COMMUNICATION, printer.PrinterName.c_str(), L0_MAXPDU);//m_pConfig->get_entry(L0_MAXPDU);
					printer.MediumType = getConfigEntry(L2_COMMUNICATION, printer.PrinterName.c_str(), L0_MEDIUMTYPE);//m_pConfig->get_entry(L0_MEDIUMTYPE);
					printer.MinDensity = getConfigEntry(L2_COMMUNICATION, printer.PrinterName.c_str(), L0_MINDENSITY);//m_pConfig->get_entry(L0_MINDENSITY);
					printer.OmitSOPClassUIDFromCreateResponse = getConfigBoolEntry(L2_COMMUNICATION, printer.PrinterName.c_str(), L0_OMITSOPCLASSUIDFROMCREATERESPONSE, false);
					printer.PresentationLUTMatchRequired = getConfigBoolEntry(L2_COMMUNICATION, printer.PrinterName.c_str(), L0_PRESENTATIONLUTMATCHREQUIRED, false);
					printer.PresentationLUTinFilmSession = getConfigBoolEntry(L2_COMMUNICATION, printer.PrinterName.c_str(), L0_PRESENTATIONLUTINFILMSESSION, false);
					printer.ResolutionID = getConfigEntry(L2_COMMUNICATION, printer.PrinterName.c_str(), L0_RESOLUTIONID);//m_pConfig->get_entry(L0_RESOLUTIONID);
					printer.SmoothingType = getConfigEntry(L2_COMMUNICATION, printer.PrinterName.c_str(), L0_SMOOTHINGTYPE);//m_pConfig->get_entry(L0_SMOOTHINGTYPE);
					printer.Supports12Bit = getConfigBoolEntry(L2_COMMUNICATION, printer.PrinterName.c_str(), L0_SUPPORTS12BIT, true);
					printer.SupportsDecimateCrop = getConfigBoolEntry(L2_COMMUNICATION, printer.PrinterName.c_str(), L0_SUPPORTSDECIMATECROP, true);
					printer.SupportsImageSize = getConfigBoolEntry(L2_COMMUNICATION, printer.PrinterName.c_str(), L0_SUPPORTSIMAGESIZE, true);
					printer.SupportsPresentationLUT = getConfigBoolEntry(L2_COMMUNICATION, printer.PrinterName.c_str(), L0_SUPPORTSPRESENTATIONLUT, true);
					printer.SupportsTrim = getConfigBoolEntry(L2_COMMUNICATION, printer.PrinterName.c_str(), L0_SUPPORTSTRIM, true);
					vec.push_back(printer);
				}

				m_pConfig->next_section(1);
			}
		}
	}

	return vec.size();
}

int CPrinterConfig::GetPrinters(list_dcmprinter_type& li)
{
	if (m_pConfig)
	{
		m_pConfig->set_section(2, L2_COMMUNICATION);
		if (m_pConfig->section_valid(2))
		{
			m_pConfig->first_section(1);
			while (m_pConfig->section_valid(1))
			{
				std::string type = m_pConfig->get_entry(L0_TYPE);

				if (_stricmp(type.c_str(), "PRINTER") == 0 || _stricmp(type.c_str(), "LOCALPRINTER") == 0)
				{
					DCMPRINTER printer;
					printer.PrinterName = m_pConfig->get_keyword(1);
					printer.Aetitle = getConfigEntry(L2_COMMUNICATION, printer.PrinterName.c_str(), L0_AETITLE);//m_pConfig->get_entry(L0_AETITLE);
					printer.Description = getConfigEntry(L2_COMMUNICATION, printer.PrinterName.c_str(), L0_DESCRIPTION);//m_pConfig->get_entry(L0_DESCRIPTION);
					printer.Hostname = getConfigEntry(L2_COMMUNICATION, printer.PrinterName.c_str(), L0_HOSTNAME);//m_pConfig->get_entry(L0_HOSTNAME);
					printer.Port = getConfigEntry(L2_COMMUNICATION, printer.PrinterName.c_str(), L0_PORT);//m_pConfig->get_entry(L0_PORT);
					printer.Type = type;
					printer.BorderDensity = getConfigEntry(L2_COMMUNICATION, printer.PrinterName.c_str(), L0_BORDERDENSITY);//m_pConfig->get_entry(L0_BORDERDENSITY);
					printer.DisableNewVRs = getConfigBoolEntry(L2_COMMUNICATION, printer.PrinterName.c_str(), L0_DISABLENEWVRS, false);
					printer.DisplayFormat = getConfigEntry(L2_COMMUNICATION, printer.PrinterName.c_str(), L0_DISPLAYFORMAT);//m_pConfig->get_entry(L0_DISPLAYFORMAT);
					printer.EmptyImageDensity = getConfigEntry(L2_COMMUNICATION, printer.PrinterName.c_str(), L0_EMPTYIMAGEDENSITY);//m_pConfig->get_entry(L0_EMPTYIMAGEDENSITY);
					printer.FilmDestination = getConfigEntry(L2_COMMUNICATION, printer.PrinterName.c_str(), L0_FILMDESTINATION);//m_pConfig->get_entry(L0_FILMDESTINATION);
					printer.FilmSizeID = getConfigEntry(L2_COMMUNICATION, printer.PrinterName.c_str(), L0_FILMSIZEID);//m_pConfig->get_entry(L0_FILMSIZEID);
					printer.ImplicitOnly = getConfigBoolEntry(L2_COMMUNICATION, printer.PrinterName.c_str(), L0_IMPLICITONLY, false);
					printer.MagnificationType = getConfigEntry(L2_COMMUNICATION, printer.PrinterName.c_str(), L0_MAGNIFICATIONTYPE);//m_pConfig->get_entry(L0_MAGNIFICATIONTYPE);
					printer.MaxDensity = getConfigEntry(L2_COMMUNICATION, printer.PrinterName.c_str(), L0_MAXDENSITY);//m_pConfig->get_entry(L0_MAXDENSITY);
					printer.MaxPDU = getConfigEntry(L2_COMMUNICATION, printer.PrinterName.c_str(), L0_MAXPDU);//m_pConfig->get_entry(L0_MAXPDU);
					printer.MediumType = getConfigEntry(L2_COMMUNICATION, printer.PrinterName.c_str(), L0_MEDIUMTYPE);//m_pConfig->get_entry(L0_MEDIUMTYPE);
					printer.MinDensity = getConfigEntry(L2_COMMUNICATION, printer.PrinterName.c_str(), L0_MINDENSITY);//m_pConfig->get_entry(L0_MINDENSITY);
					printer.OmitSOPClassUIDFromCreateResponse = getConfigBoolEntry(L2_COMMUNICATION, printer.PrinterName.c_str(), L0_OMITSOPCLASSUIDFROMCREATERESPONSE, false);
					printer.PresentationLUTMatchRequired = getConfigBoolEntry(L2_COMMUNICATION, printer.PrinterName.c_str(), L0_PRESENTATIONLUTMATCHREQUIRED, false);
					printer.PresentationLUTinFilmSession = getConfigBoolEntry(L2_COMMUNICATION, printer.PrinterName.c_str(), L0_PRESENTATIONLUTINFILMSESSION, false);
					printer.ResolutionID = getConfigEntry(L2_COMMUNICATION, printer.PrinterName.c_str(), L0_RESOLUTIONID);//m_pConfig->get_entry(L0_RESOLUTIONID);
					printer.SmoothingType = getConfigEntry(L2_COMMUNICATION, printer.PrinterName.c_str(), L0_SMOOTHINGTYPE);//m_pConfig->get_entry(L0_SMOOTHINGTYPE);
					printer.Supports12Bit = getConfigBoolEntry(L2_COMMUNICATION, printer.PrinterName.c_str(), L0_SUPPORTS12BIT, true);
					printer.SupportsDecimateCrop = getConfigBoolEntry(L2_COMMUNICATION, printer.PrinterName.c_str(), L0_SUPPORTSDECIMATECROP, true);
					printer.SupportsImageSize = getConfigBoolEntry(L2_COMMUNICATION, printer.PrinterName.c_str(), L0_SUPPORTSIMAGESIZE, true);
					printer.SupportsPresentationLUT = getConfigBoolEntry(L2_COMMUNICATION, printer.PrinterName.c_str(), L0_SUPPORTSPRESENTATIONLUT, true);
					printer.SupportsTrim = getConfigBoolEntry(L2_COMMUNICATION, printer.PrinterName.c_str(), L0_SUPPORTSTRIM, true);
					li.push_back(printer);
				}

				m_pConfig->next_section(1);
			}
		}
	}

	return li.size();
}

const char * CPrinterConfig::getConfigEntry(const char *l2_key, const char *l1_key, const char *l0_key)
{
	const char *result = "";
	if (l2_key && l1_key && l0_key && m_pConfig)
	{
		m_pConfig->select_section(l1_key, l2_key);
		if (m_pConfig->section_valid(1))
			result = m_pConfig->get_entry(l0_key);
	}

	if (result == NULL)
		return "";
	return result;
}

bool CPrinterConfig::getConfigBoolEntry(const char *l2_key, const char *l1_key, const char *l0_key, bool deflt)
{
	bool result = deflt;
	if (l2_key && l1_key && l0_key && m_pConfig)
	{
		m_pConfig->select_section(l1_key, l2_key);
		if (m_pConfig->section_valid(1))
		{
			m_pConfig->set_section(0, l0_key);
			result = m_pConfig->get_bool_value(deflt);
		}
	}
	return result;
}
